package gui.categories;

import gui.addrecipe.AddRecipe;
import gui.tables.CategoryTable;
import javax.swing.JPanel;
import java.awt.GridBagLayout;
import javax.swing.JTextField;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import org.jdom.JDOMException;

import start.Config;
import start.Start;

import xml.XMLCategoryReader;
import xml.XMLCategorySaver;

/**
 * Panel zur Verwaltung der Kategorien.
 * Beinhaltet eine CategoryTable zur Auflistung der Kateorien,
 * sowie ein Vorschaupanel, dass alle mit einer ausgewaehlten Kategorie
 * verknuepften Rezepte auflistet. Desweiteren ein Eingabefeld zum Hinzufuegen
 * einer Kategorie und mehrere Buttons zur Interaktion.
 * @author Dennis Wittkoetter
 * 
 */
public class CategoryPanel extends JPanel {
	/**ID zur Serialisierung*/
	private static final long serialVersionUID = 1L;
	
	//Daten-Objekte fuer dieses Panel
	/**XML-Saver zum Speichern der Kategorien*/
	private static XMLCategorySaver xmlsaver;
	/**XML-Reader zum Auslesen von Kategoerien*/
	private static XMLCategoryReader xmlreader;
	/**Tabelle zur Auflistung und Bearbeitung von Kategorien*/
	private final static CategoryTable table = new CategoryTable();
	
	//Layout-Objekte fuer dieses Panel
	/**Suchfeld*/
	private JTextField txtFldSearch;
	/**Vorschau-Panel*/
	private JPanel previewPanel;
	/**Button zum Hinzufuegen von Kategorien*/
	private final static JButton btnAddCat = new JButton("Kategorie hinzufügen", new ImageIcon(Start.getImgs().getPlusSmall()));
	/**Button zum Umbenennen von Kategorien*/
	private final static JButton btnRenameChoice = new JButton("Umbennen", new ImageIcon(Start.getImgs().getEditSmall()));
	/**Button zum Loeschen von Kategorien*/
	private final static JButton btnDeleteChoice = new JButton("Markierte löschen", new ImageIcon(Start.getImgs().getTrashSmall()));
	/**
	 * Konstruiert das Panel fuer die Kategorieverwaltung.
	 * @throws JDOMException 
	 * @throws IOException 
	 */
	public CategoryPanel() throws IOException, JDOMException {
		//Objekte anlegen
		xmlsaver = new XMLCategorySaver(Start.getKategoriexml());
		xmlreader = new XMLCategoryReader(Start.getKategoriexml());
		JPanel tablePanel = table.buildPanel();
				
		/**Layout einstellen*/
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 300, 0};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{0.0, 1.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		/**Textfeld zum hinzufuegen einer Kategorie erstellen*/
		txtFldSearch = new JTextField();
		txtFldSearch.setColumns(10);
		txtFldSearch.setToolTipText("Trage hier den Namen deiner neuen Kategorie ein.");
		GridBagConstraints gbc_txtFldSearch = new GridBagConstraints();
		gbc_txtFldSearch.gridwidth = 2;
		gbc_txtFldSearch.insets = new Insets(15, 6, 5, 5);
		gbc_txtFldSearch.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtFldSearch.gridx = 0;
		gbc_txtFldSearch.gridy = 0;
		add(txtFldSearch, gbc_txtFldSearch);
		//KeyListener drauf legen
		txtFldSearch.addKeyListener(new KeyListener() {
			@Override public void keyPressed(KeyEvent arg0) {
				String output = txtFldSearch.getText();
				int key = arg0.getKeyCode();
				if (key == KeyEvent.VK_ENTER) {	//Enter-Button bestaetigt Eingabe
					try {
						xmlsaver.add(output);
						xmlsaver.createXMLFile();
						AddRecipe.getLeftPanel().updateKategorien();
						table.updateFromXML(xmlreader);
						txtFldSearch.setText("");
					} catch (IOException e) {
						e.printStackTrace();
					} catch (JDOMException e) {
						e.printStackTrace();
					} 
				}
				
			}
			@Override public void keyReleased(KeyEvent arg0) {}
			@Override public void keyTyped(KeyEvent arg0) {}
		});
		
		/**Button zum hinzufuegen einer Kategorie erstellen*/
		GridBagConstraints gbc_lblAddCat = new GridBagConstraints();
		gbc_lblAddCat.anchor = GridBagConstraints.WEST;
		gbc_lblAddCat.insets = new Insets(15, 0, 5, 5);
		gbc_lblAddCat.gridwidth = 2;
		gbc_lblAddCat.gridx = 2;
		gbc_lblAddCat.gridy = 0;
		add(btnAddCat, gbc_lblAddCat);
		//ActionListener hinzufuegen
		btnAddCat.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent arg0) {
				String output = txtFldSearch.getText();
				try {
					xmlsaver.add(output);
					xmlsaver.createXMLFile();
					table.updateFromXML(xmlreader);
					AddRecipe.getLeftPanel().updateKategorien();
					txtFldSearch.setText("");
				} catch (IOException e) {
					e.printStackTrace();
				} catch (JDOMException e) {
					e.printStackTrace();
				}
			}
		});
		//KeyListener hinzufuegen
		btnAddCat.addKeyListener(new KeyListener() {
			@Override public void keyPressed(KeyEvent arg0) {
				try {
					if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {	//Enter-Button bestaetigt Eingabe
						xmlsaver.add(txtFldSearch.getText());		//Textfeld-Inhalt der Kategorie-XML hinzufuegen
						xmlsaver.createXMLFile();		//XML ueberschreieb
						table.updateFromXML(xmlreader);	//Tabelleninhalt neu laden
						AddRecipe.getLeftPanel().updateKategorien();
						txtFldSearch.setText("");
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (JDOMException e) {
					e.printStackTrace();
				}
			}
			@Override public void keyReleased(KeyEvent arg0) {}
			@Override public void keyTyped(KeyEvent arg0) {}
		});
		
		/**Tabelle erstmalig mit XML-Eintraegen fuellen*/
		table.updateFromXML(xmlreader);
		
		/**ScrollPane fuer Kategorievorschau konstruieren*/
		tablePanel.setBackground(UIManager.getColor("Button.background"));
		tablePanel.setToolTipText("Hier siehst due alle angelegten Kategorien");
		tablePanel.setBorder(new TitledBorder(null, "Kategorien", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		GridBagConstraints gbc_tablePanel = new GridBagConstraints();
		gbc_tablePanel.gridwidth = 3;
		gbc_tablePanel.insets = new Insets(0, 0, 5, 5);
		gbc_tablePanel.fill = GridBagConstraints.BOTH;
		gbc_tablePanel.gridx = 0;
		gbc_tablePanel.gridy = 1;
		add(tablePanel, gbc_tablePanel);
		
		/**leeres Vorschau-Panel zur Anzeige von verknuepften Rezepten konstruieren*/
		buildPreviewPanel();
		
		//MouseListener auf Tabelle legen
		table.getTable().addMouseListener(new MouseListener() {
			@Override public void mouseClicked(MouseEvent arg0) {
				try {
					rebuildPreviewPanel();	//PreviewPanel neu laden
					
					System.out.println(CategoryPanel.getTable().getValueAt(
							CategoryPanel.getTable().getTable().getSelectedRow(), 
							CategoryPanel.getTable().getTable().getSelectedColumn()));
				} catch (JDOMException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			@Override public void mouseEntered(MouseEvent arg0) {}
			@Override public void mouseExited(MouseEvent arg0) {}
			@Override public void mousePressed(MouseEvent arg0) {}
			@Override public void mouseReleased(MouseEvent arg0) {}
		});
		//KeyListener auf Tabelle legen
		table.getTable().addKeyListener(new KeyListener() {
			@Override public void keyTyped(KeyEvent arg0) {}
			@Override public void keyPressed(KeyEvent arg0) {}
			@Override public void keyReleased(KeyEvent arg0) {
				try {
					rebuildPreviewPanel();	//PreviewPanel neu laden
					
					if (arg0.getKeyCode() == KeyEvent.VK_ENTER)
						System.out.println(CategoryPanel.getTable().getValueAt(
								CategoryPanel.getTable().getTable().getSelectedRow(), 
								CategoryPanel.getTable().getTable().getSelectedColumn()));
				} catch (JDOMException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}			
		});
		
		/**Umbenennen-Button hinzufuegen*/
		btnRenameChoice.setEnabled(false);
		btnRenameChoice.setVisible(false);
		GridBagConstraints gbc_btnRenameChoice = new GridBagConstraints();
		gbc_btnRenameChoice.insets = new Insets(0, 0, 0, 5);
		gbc_btnRenameChoice.gridx = 1;
		gbc_btnRenameChoice.gridy = 2;
		add(btnRenameChoice, gbc_btnRenameChoice);
		btnRenameChoice.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				
			}
		});
		btnRenameChoice.addKeyListener(new KeyListener() {
			@Override public void keyPressed(KeyEvent arg0) {
				if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
					
				}
			}
			@Override public void keyReleased(KeyEvent arg0) {}
			@Override public void keyTyped(KeyEvent arg0) {}
		});
		
		/**Loeschen-Button hinzufuegen*/
		btnDeleteChoice.setEnabled(false);
		btnDeleteChoice.setToolTipText("Löscht alle abgehakten Kategorien");
		GridBagConstraints gbc_btnDeleteChoice = new GridBagConstraints();
		gbc_btnDeleteChoice.anchor = GridBagConstraints.WEST;
		gbc_btnDeleteChoice.insets = new Insets(0, 0, 0, 5);
		gbc_btnDeleteChoice.gridx = 0;
		gbc_btnDeleteChoice.gridy = 2;
		add(btnDeleteChoice, gbc_btnDeleteChoice);
		btnDeleteChoice.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent arg0) {
				try {
					table.removeCheckedEntries(xmlsaver);
					table.updateFromXML(xmlreader);
					AddRecipe.getLeftPanel().updateKategorien();
					rebuildPreviewPanel();
				} catch (JDOMException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		btnDeleteChoice.addKeyListener(new KeyListener() {
			@Override public void keyPressed(KeyEvent e) {
				try {
					if (e.getKeyCode() == KeyEvent.VK_ENTER) {
						table.removeCheckedEntries(xmlsaver);
						table.updateFromXML(xmlreader);	
					}
					AddRecipe.getLeftPanel().updateKategorien();
					rebuildPreviewPanel();
				} catch (JDOMException e1) {
					e1.printStackTrace();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			@Override public void keyReleased(KeyEvent e) {}
			@Override public void keyTyped(KeyEvent e) {}
		});
	}
	
	/**
	 * Liefert die Tabelle fuer die Kategorieverwaltung
	 * @return	Tabelle
	 */
	public final static CategoryTable getTable() {
		return table;
	}
	/**
	 * Liefert den Loeschbutton fuer das Loeschen der Kategorie
	 * @return	JButton
	 */
	public final static JButton getBtnDeleteChoice() {
		return btnDeleteChoice;
	}
	/**
	 * Konstruiert ein leeres Vorschau-Panel
	 * @throws JDOMException
	 * @throws IOException
	 */
	private void buildPreviewPanel() throws JDOMException, IOException {
		this.buildPreviewPanel(-1);
	}
	
	/**
	 * Konstruiert das Panel zur Anzeige der Vorschau
	 * @param selRow	Aktuell in der OverviewTable ausgewaehlte Zeile
	 * @throws JDOMException
	 * @throws IOException
	 */
	private void buildPreviewPanel(int selRow) throws JDOMException, IOException {
		previewPanel = new CategoryPanel_Preview(selRow);
		previewPanel.setToolTipText("Hier sind alle Rezepte aufgelistet, die der ausgewählten Kategorie angehören");
		previewPanel.setBorder(new TitledBorder(null, "zugehörige Rezepte", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		GridBagConstraints gbc_lstPreview = new GridBagConstraints();
		gbc_lstPreview.gridwidth = 2;
		gbc_lstPreview.insets = new Insets(0, 0, 5, 0);
		gbc_lstPreview.fill = GridBagConstraints.BOTH;
		gbc_lstPreview.gridx = 3;
		gbc_lstPreview.gridy = 1;
		add(previewPanel, gbc_lstPreview);
	}
	
	/**
	 * Reset des Vorschau-Panels
	 * @throws JDOMException
	 * @throws IOException
	 */
	private void rebuildPreviewPanel() throws JDOMException, IOException {
		int checkedRows = table.getCheckedRowCount();
		int selectedRows = table.getTable().getSelectedRowCount();
		
		if (Config.debugMode())
			System.out.println("MouseListener - selRow: "+checkedRows);
		
		remove(previewPanel);
		revalidate();
		repaint();
		
		//Button-Aktivitaet festlegen
		if (checkedRows < 1) {
			if (selectedRows == 1) {
				btnRenameChoice.setEnabled(true);
				buildPreviewPanel(table.getTable().getSelectedRow());
			}
			else {//if (selectedRows != 1)
				btnRenameChoice.setEnabled(false);
				buildPreviewPanel();
			}
			btnDeleteChoice.setEnabled(false);
		}
		else if (checkedRows >= 1) {
			if (selectedRows == 1) {
				btnRenameChoice.setEnabled(true);
				buildPreviewPanel(table.getTable().getSelectedRow());
			}
			else {//if (selectedRows != 1)
				btnRenameChoice.setEnabled(false);
				buildPreviewPanel();
			}
			btnDeleteChoice.setEnabled(true);
		}
	}
}
